home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-10-22 | 19.4 KB | 390 lines | [TEXT/MPS ] |
- ***** TextEditControl.c usage documentation *****/
-
- Purpose: To simplify TextEdit handling within a window.
-
- Implementing a TextEdit control does the following:
-
- 1) Makes using TextEdit in a non-dialog window easy.
- 2) The TERecord is automatically associated with the window, since
- it is in the window's control list.
- 3) The TextEdit control can have scrollbars associated with it, and these
- are also kept in the window's control list, and also associated with
- the TextEdit control.
- 4) Updating of the TERecord is much simpler, since all that is
- necessary is to draw the control (or all the window's controls with
- a DrawControls call).
- 5) What isn't handled automatically by tracking the control can be handled
- with a direct call. There are simple calls to handle TextEdit events.
- 6) Undo is already supported.
- 7) A TERecord length can be specified. This length will not be exceeded
- when editing the TERecord.
- 8) When you close the window, the TERecord is disposed of.
- (This automatic disposal can easily be defeated.)
-
-
- To create a TextEdit control, you only need a single call. For example:
-
- mode = cteVScrollLessGrow; /* TERecord read-write, with vertical scroll */
- /* that leaves space for grow box. */
-
- CTENew(rViewCtl, /* Resource ID of view control for TextEdit control. */
- window, /* Window to hold TERecord. */
- &teHndl, /* Return handle for TERecord. */
- &ctlRect, /* Rect for TextEdit view control. */
- &destRect, /* destRect for TERecord */
- &viewRect, /* viewRect for TERecord */
- &brdrRect, /* Used to frame a border. */
- 32000, /* Max size for TERecord text. */
- mode);
-
- The various choices for the TextEdit control are defined as follows:
-
- #define cteReadOnly 1
- #define cteHScroll 2
- #define cteHScrollLessGrow 6
- #define cteVScroll 8
- #define cteVScrollLessGrow 24
- #define cteActive 32
- #define cteShowActive 64
- #define cteTabSelectAll 128
- #define cteTwoStep 256
-
- cteReadOnly: Don't allow editing. When selected, don't blink a caret.
- Allow text selection and copy-to-clipboard.
- cteHScroll: Create and manage a horizontal scrollbar for the TextEdit control.
- cteHScrollLessGrow: Create and manage a horizontal scrollbar for the TextEdit control,
- but leave space for a growIcon on the right end of the scrollbar.
- cteVScroll: Create and manage a vertical scrollbar for the TextEdit control.
- cteVScrollLessGrow: Create and manage a vertical scrollbar for the TextEdit control,
- but leave space for a growIcon on the bottom end of the scrollbar.
- cteActive: Make this the initially active control for the window.
- cteShowActive: When the control is active, show that it is by drawing a selection
- border around the control. This is the new 7.0 human-interface
- method of showing which control is active. (This can be an important
- indicator because if you have readOnly TextEdit controls, they don't
- have a blinking caret. If they also don't have any text selected,
- there will be no indication that it is the active control.
- cteTabSelectAll: When using IsCtlEvent() (discussed under "! using CtlHandler.c"),
- tab changes the active TextEdit (or List) control. When a TextEdit
- control is made active, sometimes it is desirable to initially select
- all of the text for the user. Setting this bit accomplishes this.
- cteTwoStep: When using IsCtlEvent(), you may want the initial click on a TextEdit
- control to just select the control, or you may wish the click to start
- tracking in addition to selecting the control. The tracking is
- considered the second step, so by setting this bit, you will get
- tracking of the control on the initial click.
-
- Simply initialize ctlRect, destRect, viewRect, and brdrRect appropriately, and
- then call CTENew (which stands for Control TENew). If teHndl is returned
- nil, then CTENew failed. Otherwise, you now have a TextEdit control in the
- window. If it fails, it also returns an error stating why it failed
- (memFullErr or resNotFound).
-
- NOTE: There is a TextEdit bug (no way!!) such that you may need to set the
- viewRect right edge 2 bigger than the right edge of destRect. If you
- do not do this, then there will be some clipping on the right edge in
- some cases. Of course, you may want this. You may want horizontal
- scrolling, and therefore you would want the destRect substantially
- larger than the viewRect. If you don't want horizontal scrolling,
- then you probably don't want any clipping horizontally, and therefore
- you will need to set destRect.right 2 less than viewRect.right.
-
-
- If the CTENew call succeeds, you then have a TextEdit control in your
- window. It will be automatically disposed of when you close the window.
- If you don't waht this to happen, then you can detach it from the
- view control which owns it. To do this, you would to the following:
-
- viewCtl = CTEViewFromTE(theTextEditHndl);
- if (viewCtl) SetCRefCon(viewCtl, nil);
-
- The view control keeps a reference to the TERecord in the refCon.
- If the refCon is cleared, then the view control does nothing. So, all that
- is needed to detach a TERecord from a view control is to set the
- view control's refCon nil. Now if you close the window, you will still
- have the TERecord.
-
-
- To remove a TextEdit control completely from a window, you make one call:
-
- CTEDispose(theTextEditHndl);
-
- This disposes of the TERecord, the view control, and any scrollbar
- controls that were created when the TextEdit control was created with
- the call CTENew.
-
-
- Events for TERecord are handled nearly automatically. You can
- make one of 3 calls:
-
- CTEClick(eventPtr, &action);
- CTEEvent(eventPtr, &action);
- CTEKey(eventPtr);
-
- In each case, if the event was handled, true is returned. CTEEvent simply
- calls either CTEClick or CTEKey, whichever is appropriate.
-
-
- Another call you will want to use is CTEEditMenu. This is used to set the
- state of cut/copy/paste/clear for TextEdit controls. It checks the active
- control to see if text is selected, if the control is read-only, etc.
- Based on this information, it sets cut/copy/paste/clear either active
- or inactive. If any menu items are set active, it returns true.
-
-
- One more high-level call is CTEUndo(). In response to an undo menu item
- being selected by the user, just call CTEUndo(), and the edits the user
- has made will be undone. (This includes undoing an undo.)
-
-
- The last high-level call for managing the edit menu is CTEClipboard. Call it
- when you want to do a cut/copy/paste/clear for the active TextEdit control.
- The value to pass is as follows:
-
- 2: cut
- 3: copy
- 4: paste
- 5: clear
-
- These are the same values you would pass to a DA for these actions.
-
-
-
- Here is a list of the functions and a description as to their purpose:
-
- void CTEActivate(Boolean active, TEHandle teHndl);
- /* Activate this TextEdit record. If another is currently active, deactivate
- ** that one. The view control for this TextEdit record is also flagged to
- ** indicate which was the last active one for this window. If the previous
- ** active TextEdit record was in the same window, then flag the old one off
- ** for this window. The whole point for this per-window flagging is so that
- ** activate events can reactivate the correct TextEdit control per window. */
-
- Boolean CTEClick(EventRecord *event, short *action);
- /* This is called when a mouseDown occurs in the content of a window. It
- ** returns true if the mouseDown caused a TextEdit action to occur. Events
- ** that are handled include if the user clicks on a scrollbar that is
- ** associated with a TextEdit control.
- **
- ** if CTEClick returns false, action is 0
- ** if CTEClick returns true, action is:
- ** -1 if control was activated by clicking on the TextEdit control or related scrollbar.
- ** 0 if control that was clicked on was already active. */
-
-
- void CTEClipboard(short menuID);
- /* Do the cut/copy/paste/clear operations for the currently active
- ** TextEdit control. Caller assumes appropriateness of the call. Typically,
- ** this routine won't be called at an inappropriate time, since the menu
- ** item should be enabled or disabled correctly.
- ** Use CTEEditMenu to set the menu items undo/cut/copy/paste/clear correctly
- ** for the active TextEdit control. Since undo isn't currently supported,
- ** all that CTEEditMenu does for the undo case is to deactivate it right now. */
-
- ControlHandle CTECtlHit(void);
- /* The TextEdit control that was hit by calling FindControl is saved in a
- ** global variable, since the CDEF has no way of returning what kind it was.
- ** To determine that it was a TextEdit control that was hit, first call this
- ** function. The first call returns the old value in the global variable,
- ** plus it resets the global to nil. Then call FindControl(), and then
- ** call this function again. If it returns nil, then a TextEdit control
- ** wasn't hit. If it returns non-nil, then it was a TextEdit control that
- ** was hit, and specifically the one returned. */
-
- void CTEDispose(TEHandle teHndl);
- /* Disposes of the TERecord, TextEdit control, and any related scrollbars. */
-
- TEHandle CTEDisposeView(ControlHandle viewCtl);
- /* Dispose of the view control and related scrollbars. This function also
- ** returns the handle to the TextEdit record, since it was just orphaned.
- ** Use this function if you want to get rid of a TextEdit control, but you
- ** want to keep the TextEdit record. */
-
- short CTEDocHeight(TEHandle teHndl);
- /* Returns the full document height. */
-
- Boolean CTEEditMenu(Boolean *activeItem, short editMenu, short undoID, short cutID);
- /* Enable or disable edit menu items based on the active TextEdit control.
- ** You pass the menu ID of the undo item in undoID, and the menu ID of the
- ** cut item in cutID. If undoID or cutID is non-zero, then some action is
- ** performed. If you pass a non-zero value for cutID, then the other menu
- ** items cut/copy/paste/clear are updated to reflect the status of the
- ** active TextEdit control. */
-
- Boolean CTEEvent(EventRecord *event, short *action);
- /* Handle the event if it applies to the active TextEdit control. If some
- ** action occured due to the event, return true.
- **
- ** if event not handled, false is returned and action is 0
- ** if event handled, true is returned and action is:
- ** -1: an inactive control was clicked on and it was made active.
- ** 0: an active control was clicked on and tracked.
- ** 1: the control took the keypress, but no change occured to the TERecord.
- ** 2: the control took the keypress and the TERecord changed. */
-
- void CTEFakeClick(short newStart, short newEnd, Boolean extend, TEHandle teHndl);
- /* Select or reselect a range of text without flashing or lurching. */
-
- TEHandle CTEFindActive(WindowPtr window);
- /* Returns the active TextEdit control, if any. If nil is passed in, then
- ** the return value represents whatever TextEdit control is active, independent
- ** of what window it is in. If a window is passed in, then it returns a
- ** TextEdit control only if the active control is in the specified window.
- ** If the active TextEdit control is in some other window, then nil is returned. */
-
- Boolean CTEFindCtl(WindowPtr window, EventRecord *event, TEHandle *teHndl, ControlHandle *ctlHit);
- /* This determines if a TextEdit control was clicked on directly. This does
- ** not determine if a related scrollbar was clicked on. If a TextEdit
- ** control was clicked on, then true is returned, as well as the TextEdit
- ** handle and the handle to the view control. */
-
- TEHandle CTEFromScroll(ControlHandle scrollCtl, ControlHandle *retCtl);
- /* Find the TextEdit record that is related to the indicated scrollbar. */
-
- void CTEHide(TEHandle teHndl);
- /* Hide the designated TextEdit control and related scrollbars. */
-
- void CTEIdle(void);
- /* Blink the caret in the active TextEdit control. The active TextEdit
- ** control may be read-only, in which case the caret does not blink. */
-
- short CTEKey(EventRecord *event);
- /* See if the keypress event applies to the TextEdit control, and if it does,
- ** handle it and return non-zero.
- **
- ** if CTEKey returns 0, TextEdit control didn't handle the event.
- ** if CTEKey returns 1, TextEdit control did handle the event, but the TERecord didn't change.
- ** if CTEKey returns 2, TextEdit control did handle the event, and the TERecord changed.
-
- void CTEMove(TEHandle teHndl, short newH, short newV);
- /* This function is used to move a TextEdit control. Pass it the TextEdit
- ** record to move, plus the new position. It will move the TextEdit control,
- ** along with any scrollbars the control may have. All areas that need
- ** updating are cleared and invalidated. */
-
- OSErr CTENew(short viewID, WindowPtr window, TEHandle *teHndl, Rect *cRect,
- Rect *dRect, Rect *vRect, Rect *bRect, short maxTextLen, short mode);
- /* Create a new TextEdit control. See the comments at the beginning of this
- ** file for more information. */
-
- void CTENewUndo(ControlHandle viewCtl, Boolean alwaysNewUndo);
- /* Save the data (if appropriate) so that user can undo. */
-
- ControlHandle CTENext(WindowPtr window, TEHandle *teHndl, ControlHandle ctl);
- /* Get the next TextEdit control in the window. You pass it a control handle
- ** for the view control, or nil to start at the beginning of the window.
- ** It returns both a TextEdit handle and the view control handle for that
- ** TextEdit record. If none is found, nil is returned. This allows you to
- ** repeatedly call this function and walk through all the TextEdit controls
- ** in a window. */
-
- short CTENumTextLines(TEHandle teHndl);
- /* Return the number of lines of text. This is because there is a bug in
- ** TextEdit where the number of lines returned is incorrect if the text
- ** ends with a c/r. This function adjusts for this bug. */
-
- short CTENumViewLines(TEHandle teHndl);
- /* Return the number of text lines in the view area. */
-
- OSErr CTEPrint(TEHandle teHndl, short *offset, Rect *rct);
- /* Use this function to print the contents of a TextEdit record. Pass it a
- ** TextEdit handle, a pointer to a text offset, and a pointer to a rect to
- ** print the text in. The offset should be initialized to what character
- ** in the TextEdit record you wish to start printing at (most likely 0).
- ** The print function prints as much text as will fit in the rect, and
- ** then updates the offset to tell you what is the first character that didn't
- ** print. You can then call the print function again with another rect with
- ** this new offset, and it will print the text starting at the new offset.
- ** This method is very useful when a single TextEdit record is longer than a
- ** single page, and you wish the text to break at the end of the page.
- ** The bottom of rect is also updated, along with the offset. The bottom edge
- ** of the rect is changed to reflect the actual bottom of the text printed.
- ** This is useful because the rect passed in didn't necessarily hold an
- ** integer number of lines of text. The bottom of the rect is adjusted so
- ** it exactly holds complete lines of text.
- ** It is also possible that the rect could hold substantially more lines of
- ** text than there are remaining. Again, in this situation, the bottom of
- ** rect is adjusted so that the rect tightly bounds the text printed.
- ** The remaining piece of information passed back is an indicator that the
- ** text through the end of the TextEdit record was printed. When the end
- ** of the text is reached, the offset for the next text to be printed is
- ** returned as -1. This indicates that processing of the TextEdit record
- ** is complete. */
-
- Boolean CTEReadOnly(TEHandle teHndl);
- /* Return if the TextEdit control is read/write (true) or read-only (false). */
-
- ControlHandle CTEScrollFromTE(TEHandle teHndl, Boolean vertScroll);
- /* Return the control handle for the TextEdit control's scrollbar, either
- ** vertical or horizontal. If the scrollbar doesn't, nil is returned. */
-
- ControlHandle CTEScrollFromView(ControlHandle viewCtl, Boolean vertScroll);
- /* Return the control handle for the scrollbar related to the view control,
- ** either horizontal or vertical. If the scrollbar doesn't exist, return nil. */
-
- void CTESetKeyFilter(TEHandle teHndl, CTEKeyFilterProcPtr proc);
- /* A TextEdit control can have an optional key filter, which is called whenever
- ** CTEKey() is called. If you pass in nil, then the filtering is turned off.
- ** This allows individual TextEdit controls to handle their own filtering.
- ** The filter procedure is of the form:
- ** Boolean (*CTEKeyFilterProcPtr)(TEHandle teHndl, EventRecord *event, Boolean *handled);
- ** If true is returned, then CTEKey() is aborted, and the value in "handled" is
- ** returned. By having a separate abort value and return value, you can determine
- ** if processing of the event should be continued or not, independent of whether
- ** or not you aborted CTEKey(). */
-
- void CTESetSelect(short start, short end, TEHandle teHndl);
- /* Select a range of text. TESetSelect can't be used alone because it doesn't
- ** update the scrollbars. This function calls TESetSelect, and then fixes up
- ** the scrollbars. */
-
- void CTEShow(TEHandle teHndl);
- /* Show the designated TextEdit control and related scrollbars. */
-
- void CTESize(TEHandle teHndl, short dx, short dy, Boolean newDest);
- /* This function is used to resize a TextEdit control. Pass it the TextEdit
- ** record to resize, plus the new horizontal and vertical size. It will
- ** resize the TextEdit control, realign the text, if necessary, plus it will
- ** resize and adjust any scrollbars the TextEdit control may have. All areas
- ** that need updating are cleared and invalidated. */
-
- Handle CTESwapText(TEHandle teHndl, Handle newText, Boolean update);
- /* Swap the TextEdit text handle with the text handle passed in. */
-
- WindowPtr CTETargetInfo(TEHandle *teHndl, Rect *teView);
- /* Return information for the currently active TextEdit control. The currently
- ** active TextEdit control is stored in gActiveTEHndl, and can be accessed
- ** directly. If gActiveTEHndl is nil, then there is no currently active one.
- ** The information that we return is the viewRect and window of the active
- ** TextEdit control. This is information that could be gotten directly, but
- ** this call makes it a little more convenient. */
-
- void CTEUndo(void);
- /* Perform an undo function for the TextEdit control. */
-
- void CTEUpdate(TEHandle teHndl, ControlHandle ctl, Boolean justShowActive);
- /* Draw the TextEdit control and frame. */
-
- ControlHandle CTEViewFromTE(TEHandle teHndl);
- /* Return the control handle for the view control that owns the TextEdit
- ** record. Use this to find the view to do customizations such as changing
- ** the update procedure for this TextEdit control. */
-
- Boolean CTEWindActivate(WindowPtr window);
- /* Call this when a window with TextEdit controls is being activated. This
- ** will make the TextEdit control that was last active in this window the
- ** active TextEdit control again. If it can't find one that was the last
- ** active control, it makes the first one it finds the active control. */
-
- void CTEAdjustTEBottom(TEHandle teHndl);
- /* This function is called after an edit to make sure that there is no extra
- ** white space at the bottom of the viewRect. If there are blank lines at
- ** the bottom of the viewRect, and there is text scrolled off the top of the
- ** viewRect, then the TextEdit control is scrolled to fill this space, or as
- ** much of it as possible. */
-
- void CTEAdjustScrollValues(TEHandle teHndl);
- /* Bring the scrollbar values up to date with the current document position
- ** and length. */
-
-